home *** CD-ROM | disk | FTP | other *** search
/ Fritz: All Fritz / All Fritz.zip / All Fritz / FILES / MUSIUSIC / MIDICOLL.LZH / DUMPST.ARC / DUMPSTER.PAS < prev   
Pascal/Delphi Source File  |  1980-01-01  |  48KB  |  1,848 lines

  1. {$U-,C-}
  2.  
  3. Program Dumpster;
  4.  
  5. (*        Data Dump Program By            Randy Grohs
  6.                                      BBS: Midwest MIDI BBS
  7.                                           1 (405) 733-3102   *)
  8.  
  9. Const
  10.    Choices        = 4;
  11.    MaxRecs        = 50;
  12.    ByteBufferSize = 6400;
  13.  
  14. Var
  15.       Ch,Ch2,Drive          :CHar;
  16.  
  17.  
  18. (* Does System Exclusive Data Dumps directly to and from Disk *)
  19.  
  20. (* Special Keys ***********************************************)
  21.  
  22. Const
  23.   F1   =   #59;
  24.   F2   =   #60;
  25.   F3   =   #61;
  26.   F4   =   #62;
  27.   F5   =   #63;
  28.   F6   =   #64;
  29.   F7   =   #65;
  30.   F8   =   #66;
  31.   F9   =   #67;
  32.   F10  =   #68;
  33.   ShiftF1  =   #84;
  34.   ShiftF2  =   #85;
  35.   ShiftF3  =   #86;
  36.   ShiftF4  =   #87;
  37.   ShiftF5  =   #88;
  38.   ShiftF6  =   #89;
  39.   ShiftF7  =   #90;
  40.   ShiftF8  =   #91;
  41.   ShiftF9  =   #92;
  42.   ShiftF10 =   #93;
  43.   CtrlF1   =   #94;
  44.   CtrlF2   =   #95;
  45.   CtrlF3   =   #96;
  46.   CtrlF4   =   #97;
  47.   CtrlF5   =   #98;
  48.   CtrlF6   =   #99;
  49.   CtrlF7   =   #100;
  50.   CtrlF8   =   #101;
  51.   CtrlF9   =   #102;
  52.   CtrlF10  =   #103;
  53.   AltF1    =   #104;
  54.   AltF2    =   #105;
  55.   AltF3    =   #106;
  56.   AltF4    =   #107;
  57.   AltF5    =   #108;
  58.   AltF6    =   #109;
  59.   AltF7    =   #110;
  60.   AltF8    =   #111;
  61.   AltF9    =   #112;
  62.   AltF10   =   #113;
  63.   LeftArrow      =   #75;
  64.   RightArrow     =   #77;
  65.   UpArrow        =   #72;
  66.   DownArrow      =   #80;
  67.   HomeKey        =   #71;
  68.   EndKey         =   #79;
  69.   PageUp         =   #73;
  70.   PageDown       =   #81;
  71.   CtrlLeftArrow  =   #115;
  72.   CtrlRightArrow =   #116;
  73.   CtrlHomeKey    =   #119;
  74.   CtrlEndKey     =   #117;
  75.   CtrlPageUp     =   #132;
  76.   CtrlPageDown   =   #118;
  77.  
  78. Var PossibleChoicesSet:Set Of Char;
  79.  
  80.  
  81.  
  82.  
  83. (* MPU Commands and Some Colors *****************************************)
  84.  
  85. Type
  86.      AnyStr          =  String[255];
  87.      CharSet         =  Set Of Char;
  88.      Str2            =  string[2];
  89.      Str8            =  string[8];
  90.      Str10           =  String[10];
  91.      Str12           =  String[12];
  92.      Str20           =  String[20];
  93.      Str25           =  String[25];
  94.      Str40           =  String[10];
  95.      Str80           =  string[80];
  96.  
  97. Const
  98.  
  99.   BlueColor       = 1;
  100.   GreenColor      = 2;
  101.   RedColor        = 12;
  102.   WhiteColor      = 15;
  103.   YellowColor     = 14;
  104.   MagentaColor    = 5;
  105.   BlackColor      = 0;
  106.   Dsr             = $80;
  107.   Drr             = $40;
  108.   Ack             = $FE;
  109.   DataPort        = $330;
  110.   StatPort        = $331;
  111.   EOX             = $F7;
  112.  
  113.   StartPlay           = $0A;
  114.   ContinuePlay        = $0B;
  115.   StartRecord         = $22;
  116.   ContinueRecord      = $23;
  117.   StopAll             = $15;
  118.   StartOverdub        = $2A;
  119.   IntClock            = $80;
  120.   FskCLock            = $81;
  121.   MidiClock           = $82;
  122.   MetronomeOn         = $85;
  123.   MetronomeOff        = $84;
  124.   MidiThruOn          = $89;
  125.   MidiThruOff         = $88;
  126.   DataInStopOn        = $8B;
  127.   DataInStopOff       = $8A;
  128.   SendMeasureEndOff   = $8C;
  129.   SendMeasureEndOn    = $8D;
  130.   ConductorOff        = $8E;
  131.   ConductorOn         = $8F;
  132.   RealTimeAffOn       = $91;
  133.   RealTimeAffOff      = $90;
  134.   ClockToHostOn       = $95;
  135.   ClockToHostOff      = $94;
  136.   ExclusiveOn         = $97;
  137.   ExclusiveOff        = $96;
  138.   ClearPlayCounters   = $B8;
  139.   ClearPlayMap        = $B9;
  140.   ClearRecordCounters = $BA;
  141.   SetTempo            = $E0;
  142.   NoRealTime          = $32;
  143.   ThruOff             = $33;
  144.   WithTimingByte      = $34;
  145.   ExclusiveThruOn     = $37;
  146.   CommonOn            = $38;
  147.   RealTimeOn          = $39;
  148.   UartOn              = $3F;
  149.   SystemReset         = $FF;
  150.   SetActiveTracks     = $EC;
  151.   BenderOn            = $87;
  152.   BenderOff           = $86;
  153.  
  154.  
  155. Function Power(I1,I2:Integer):Integer;
  156. Var I,I3:Integer;
  157. Begin
  158.   For I:= 1 to I2 Do
  159.     I3:=I3*I1;
  160.   Power:=I3;
  161. End;
  162.  
  163.  
  164. Procedure ShortBeep;
  165. Begin
  166.   Sound(880);
  167.   NoSound;
  168. End;
  169.  
  170.  
  171.  
  172. Function Hex(B:Byte):Str2;
  173.   Const
  174.     H:Array [0..15] of Char = '0123456789ABCDEF';
  175.   Begin
  176.     Hex := H [B Shr 4] + H [B and 15];
  177.   End;
  178.  
  179.  
  180. (* These three subroutines (getdata, putdata and putcmd) should be       *)
  181. (* modified for programs designed for real time use.  More specifically, *)
  182. (* the Keypressed function slows down execution time considerably.       *)
  183.  
  184.  
  185.  
  186. Procedure GetData (Var MidiData:Byte);
  187.   Var
  188.     J:Byte;
  189.   Begin
  190.     J:= 0;
  191.     Repeat
  192.       J:=Port[StatPort];
  193.     Until ((J and Dsr) = 0) or KeyPressed;
  194.     If KeyPressed then Read(Kbd,CH);
  195.     MidiData:=Port[Dataport];
  196.     ShortBeep;
  197.   End;
  198.  
  199. Procedure PutData (MidiData:Byte);
  200.   Var J:Byte;
  201.   Begin
  202.     J := 0;
  203.     Repeat
  204.       J :=Port[StatPort];
  205.       If (J and Dsr) = 0 Then Repeat
  206.         GetData(J);
  207.         J:= Port[Statport];
  208.       Until ((J and Dsr) <> 0) or KeyPressed;
  209.     Until ((J and Drr) = 0) or KeyPressed;
  210.     If KeyPressed then Read(Kbd,CH);
  211.     Port[DataPort] := MidiData;
  212.     ShortBeep;
  213.   End;
  214.  
  215. Procedure PutCmd (Cmd:Byte);
  216.   Var I:Integer;
  217.       J:Byte;
  218.   Begin
  219.     J:=0;
  220.     IF (Cmd<>SystemReset) Then Repeat
  221.       J:=Port[StatPort];
  222.     Until ((J and Drr) = 0) or KeyPressed;
  223.     If KeyPressed then Read(Kbd,CH);
  224.     Port[StatPort]:=Cmd;
  225.     ShortBeep;
  226.     Repeat
  227.       GetData(J);
  228.     Until (J=Ack) OR KeyPressed Or ((J<>Ack) and (Cmd=SystemReset));
  229.     If KeyPressed then Read(Kbd,CH);
  230.   End;
  231.  
  232.  
  233.  
  234. function ConstStr(C : Char; N : Integer) : AnyStr;
  235. var
  236.   S : AnyStr;
  237. begin
  238.   if N < 0 then
  239.     N := 0;
  240.   S[0] := Chr(N);
  241.   FillChar(S[1],N,C);
  242.   ConstStr := S;
  243. end;
  244.  
  245. (*  Beep sounds the terminal bell or beeper *)
  246.  
  247. procedure Beep;
  248. begin
  249.      Sound(220);Delay(50);
  250.      Sound(440);Delay(50);
  251.      Sound(880);Delay(100);
  252.      NoSound;
  253. end;
  254.  
  255.  
  256. function UpcaseStr(S : AnyStr) : AnyStr;
  257. var
  258.   P : Integer;
  259. begin
  260.   for P := 1 to Length(S) do
  261.     S[P] := Upcase(S[P]);
  262.   UpcaseStr := S;
  263. end;
  264.  
  265. (* Ascii Graphic Chars *****************************************)
  266.  
  267. Type
  268.      GraphSetType = Record
  269.                       LLCorner,
  270.                       HLine,
  271.                       VLine,
  272.                       ULCorner,
  273.                       URCorner,
  274.                       LRCorner        :  Char;
  275.                     End; {GraphSetType}
  276. Var
  277.      GraphSet : Array[1..2] Of GraphSetType;
  278.  
  279. Procedure SetGraphSet;
  280. Begin
  281.   With GraphSet[1] DO Begin
  282.     LLCorner            := Chr(192);
  283.     ULCorner            := chr(218);
  284.     HLine               := chr(196);
  285.     VLine               := Chr(179);
  286.     LRCorner            := chr(217);
  287.     URCorner            := chr(191);
  288.   End; {With}
  289.   With GraphSet[2] Do Begin
  290.     LLCorner            := Chr(200);
  291.     ULCorner            := Chr(201);
  292.     HLine               := chr(205);
  293.     VLine               := Chr(186);
  294.     LRCorner            := chr(188);
  295.     URCorner            := chr(187);
  296.   End; {With}
  297. End;
  298.  
  299.  
  300. Procedure DrawTextBox( Lines       :Integer ; Prompt,BottomPrompt:AnyStr;
  301.                        X1,Y1,X2,Y2 :Integer);
  302. Var I:Integer;
  303. Begin
  304.   If (Lines>2) or (Lines<1) Then Lines:=2;
  305.   With GraphSet[Lines] Do Begin
  306.     GotoXY(X1,Y1);Write(ULCorner);
  307.     For I:= X1+1 to X2-1 Do Write(HLine);
  308.     Write(URCorner);
  309.     For I:= Y1+1 to Y2-1 Do Begin
  310.       GotoXY(X1,I);Write(VLine);
  311.       GotoXY(X2,I);Write(VLine);
  312.     End;{For}
  313.     GotoXY(X1,Y2);Write(LLCorner);
  314.     For I:= X1+1 to X2-1 Do Write(HLine);
  315.     Write(LRCorner);
  316.     GotoXY(X1+((X2-X1) Div 2)-(Length(Prompt) Div 2),Y1);Write(Prompt);
  317.     GotoXY(X1+((X2-X1) Div 2)-(Length(BottomPrompt) Div 2),Y2);Write(BottomPrompt);
  318.   End;{With}
  319. End;{DrawBox}
  320.  
  321.  
  322. (* Main Type and Var Declarations  ****************************************)
  323.  
  324. Type
  325.     ByteBufferType = Array[1..ByteBufferSize] of Byte;
  326.     VoiceType = Array[1..128] of Byte;
  327.     FormatType = Array[1..6] of Byte;
  328.     VoiceArrayType = Array[1..32] of VoiceType;
  329.     VoiceNameArrayType = Array[1..32] of Str10;
  330.     Str20ArrayType     = Array[1..100] of Str20;
  331.     RequestType = Record
  332.                     Notes         : Str20;
  333.                     RL            : Integer;
  334.                     RequestBuffer : Array[1..60] of Byte;
  335.                   End;
  336.     BankType = Record
  337.                  NormalFormat : Boolean;
  338.                  Buffer       : ByteBufferType;
  339.                  Pos,
  340.                  Len          : Integer;
  341.                  BankName     : Str20;
  342.                  Notes        : Str20;
  343.                  VoiceName    : VoiceNameArrayType;
  344.                  Voice        : VoiceArrayType;
  345.                  CheckSum     : Byte;
  346.                  Saved,
  347.                  Exists       : Boolean;
  348.                End;
  349.  
  350. Const
  351.    VoiceFormatBytes : FormatType = ($F0,$43,$00,$09,$20,$00);
  352.    FunctionFormatBytes : FormatType = ($F0,$43,$00,$02,$20,$00);
  353.  
  354. Var AString,FileName,Subdir,
  355.     AFileName,DiskFileName:AnyStr;
  356.     Choice,I,J,K,X,Y      :Integer;
  357.     MaskStr,DefaultMaskStr:Str12;
  358.  
  359.     Bank                  :Array[1..2] of BankType;
  360.  
  361.     DumpRequestFile       :File of RequestType;
  362.  
  363.     TempBank,
  364.     ThisBank              :BankType;
  365.  
  366.     B,AByte               :Byte;
  367.  
  368.     CurrentVoice,
  369.     ThisVoice,
  370.     Cluster               :VoiceType;
  371.  
  372.  
  373.     AByteFile             :File of Byte;
  374.     TestFile,
  375.     DiskFile,
  376.     AFile                 :File;
  377.     ByteBuffer            :ByteBufferType;
  378.  
  379.     ThisFormat            :FormatType;
  380.  
  381.     ScreenNum,
  382.     ActiveBank,
  383.     NoOfRecsToRead,
  384.     Remaining,
  385.     BufferLength,
  386.     Position              :Integer;
  387.  
  388.     EscapeNow,
  389.     Exit,OverWriteYN,OK   :Boolean;
  390.     TC,TC2                :Char;
  391.  
  392.  
  393.  
  394.  
  395.  
  396. (* Some screen I/O subroutines  ****************************************)
  397.  
  398. Procedure InverseColor;
  399. Begin
  400.   TextColor(WhiteColor);
  401.   TextBackGround(BlueColor);
  402. End;
  403.  
  404. Procedure NormalColor;
  405. Begin
  406.   TextColor(YellowColor);
  407.   TextBackGround(BlackColor);
  408. End;
  409.  
  410. Procedure SetRedColor;
  411. Begin
  412.   TextColor(WhiteColor);
  413.   TextBackGround(RedColor);
  414. End;
  415.  
  416. Procedure ClearBox( Code:Integer );
  417. Var I,X,Y:Integer;
  418. Begin
  419.   If Code=3 Then
  420.     I:=1
  421.   Else
  422.     I:=Code;
  423.   Repeat
  424.     X:=3+(40*(I-1));
  425.     For Y:=6 to 21 do Begin
  426.       GotoXY(X,Y);Write(ConstStr(' ',37));
  427.     End;{For}
  428.     I:=I+1;
  429.   Until (I>2) or (Code<>3);
  430. End;
  431.  
  432.  
  433. Procedure Message ( Code : Integer;
  434.                     Strn : AnyStr   );
  435. Var CH:Char;
  436.     X:Integer;
  437. Begin
  438.   If Code=2 Then
  439.     SetRedColor
  440.   Else
  441.     InverseColor;
  442.   GotoXY(1,24);
  443.   Write(ConstStr(' ',39-(Length(Strn) Div 2)),Strn);
  444.   X:=WhereX;
  445.   Write(ConstStr(' ',80-X));
  446.   If Code<>0 Then Beep;
  447.   If Code=2 Then Begin
  448.     Repeat Until KeyPressed;
  449.     Read(Kbd,CH);
  450.     EscapeNow := (CH=#27);
  451.   End;
  452.   NormalColor;
  453. End;
  454.  
  455.  
  456. Procedure GetString ( Prompt : AnyStr;
  457.                   Var S      : AnyStr;
  458.                       X,Y,L  : Integer);
  459.  
  460. const
  461.   UnderScore  =  '_';
  462.  
  463. Var X2,Y2,PL,P,J:Integer;
  464.     TC2,Ch:Char;
  465.     First:Boolean;
  466.  
  467. Begin
  468.   InverseColor;
  469.   PL:=Length(Prompt);
  470.   First:=true;
  471.   X2:=X;Y2:=Y;
  472.   GotoXY(X,Y);Write(ConstStr(UnderScore,PL+L));
  473.   GotoXY(X,Y);Write(Prompt);
  474.   X:=WhereX;Y:=WhereY;
  475.   GotoXY(X,Y);Write(S);
  476.   If Y=24 Then Write(ConstStr(' ',80-X));
  477.   P := 0;
  478.   CH:=#1;
  479.   repeat
  480.     Tc2:=#1;
  481.     TextColor(WhiteColor);
  482.     GotoXY(X+P,Y); Read(Kbd,Ch);
  483.     case Ch of
  484.       #1        : ;
  485.       #27       : Begin
  486.                      Read(kbd,Tc2);
  487.                      case TC2 of
  488.                        #83: if P < Length(S) then
  489.                               begin
  490.                                Delete(S,P + 1,1);
  491.                                Write(Copy(S,P + 1,L),UnderScore);
  492.                               end;
  493.                        'K': If P>0 then P:=P-1;
  494.                        'M': If P<Length(S) Then P:=P+1;
  495.                    #1,#27 : EscapeNow:=True;
  496.                      end;{case}
  497.                   end;
  498.       #32..#126 : if P < L then
  499.                     begin
  500.                       If First Then Begin
  501.                         Write(Copy(S,P + 1,L),UnderScore);
  502.                         Delete(S,P + 1,L);
  503.                         GotoXY(X+P,Y);
  504.                       End;{If}
  505.                       First:=False;
  506.                       if Length(S) = L then
  507.                         Delete(S,L,1);
  508.                       P := P + 1;
  509.                       Delete(S,P,1);
  510.                       Insert(Ch,S,P);
  511.                       Write(Copy(S,P,L));
  512.                     end
  513.                   else
  514.                     Beep;
  515.       ^A        : P := 0;
  516.       ^F        : P := Length(S);
  517.       ^G        : if P < Length(S) then
  518.                   begin
  519.                     Delete(S,P + 1,1);
  520.                     Write(Copy(S,P + 1,L),UnderScore);
  521.                   end;
  522.       ^H,#127   : if P > 0 then
  523.                   begin
  524.                     Delete(S,P,1);
  525.                     Write(^H,Copy(S,P,L),UnderScore);
  526.                     P := P - 1;
  527.                   end
  528.                   else Beep;
  529.       ^Y        : begin
  530.                     Write(ConstStr(UnderScore,Length(S) - P));
  531.                     Delete(S,P + 1,L);
  532.                   end;
  533.       ^M        : ;
  534.     Else
  535.       Beep;
  536.     end;  {of case}
  537.   until (Ch = ^M) or EscapeNow;
  538.   P := Length(S);
  539.   NormalColor;
  540.   GoTOXY(X2,Y2);Write(Prompt,S);
  541.   GotoXY(X + P , Y);
  542.   Write('' :L - P);
  543.   If Y=24 Then Write(ConstStr(' ',80-X));
  544. End;
  545.  
  546.  
  547.  
  548. Procedure GetChar (    Code   : Integer;
  549.                        Prompt : AnyStr;
  550.                   Var  Ch     : Char   );
  551. Begin
  552.   If Code=2 Then
  553.     SetRedColor
  554.   Else If Code=1 Then
  555.     InverseColor
  556.   Else
  557.     NormalColor;
  558.   GotoXY(1,24);
  559.   Write(Prompt);
  560.   If Code=2 Then Beep;
  561.   Repeat Until Keypressed;
  562.   Read(Kbd,CH);
  563.   EscapeNow := (CH=#27);
  564.   NormalColor;
  565. End;
  566.  
  567. (* File and Buffer IO  ****************************************)
  568.  
  569.  
  570. Function Other(I:Integer):Integer;
  571. Begin
  572.   Other:=(I Mod 2) + 1;
  573. End;
  574.  
  575.  
  576. Procedure CheckTheSum (      Voices : VoiceArrayType ;
  577.                         Var SumByte : Byte                            );
  578.  
  579. Const Nums : Array[0..8] of Byte = ($0,$1,$2,$4,$8,$10,$20,$40,$80);
  580.  
  581. Var   J,I:Integer;
  582.       B,B2,B3,B4:Byte;
  583. (*  This CHECKSUM routine finds the Two's complement of the sum      *)
  584. (*  of the databytes.                                                *)
  585. Begin
  586.   B:=0;
  587.   For J:=1 to 32 do
  588.     For I:=1 to 128 do
  589.       B:=B + Voices[J,I];
  590.   B:=B mod 128;
  591.   B:=(Not B) + 1;
  592. End;
  593.  
  594.  
  595. Function DiskExist(AStr:AnyStr):Boolean;
  596. Begin
  597.   Assign(TestFile,ASTR);
  598.   {$I-}
  599.   Reset(TestFile);
  600.   DiskExist:=(IOResult=0);
  601.   {$I+}
  602.   Repeat Until (IOResult=0);
  603.   Close(TestFile);
  604. End;
  605.  
  606.  
  607. Function DiskValid(AStr:AnyStr):Boolean;
  608. Begin
  609.   Assign(TestFile,ASTR);
  610.   {$I-}
  611.   ReWrite(TestFile);
  612.   DiskValid:=(IOResult=0);
  613.   {$I+}
  614.   Repeat Until (IOResult=0);
  615.   Close(TestFile);
  616. End;
  617.  
  618. Procedure Uart;
  619. Var B:Byte;
  620. Begin
  621.   Port[StatPort]:=SystemReset;
  622.   B:=Port[StatPort];
  623.   If (B and Dsr) = 0 Then GetData(B);
  624.   PutCmd(UartOn);
  625. End;
  626.  
  627.  
  628. Procedure GetByte (Var B:Byte);
  629. Begin
  630.   B:=ByteBuffer[Position];
  631.   Position:=Position+1;
  632. End;
  633.  
  634. Procedure PutByte (B:Byte);
  635. Begin
  636.   BufferLength:=BufferLength+1;
  637.   ByteBuffer[BufferLength]:=B;
  638. End;
  639.  
  640. Procedure GetBuffer( Source:Integer );
  641. Var FS,Stat,I:Integer;
  642.     J,B:Byte;
  643.     Ch:Char;
  644.     NormFmt:Boolean;
  645. Begin
  646.   NormFmt:=True;
  647.   BufferLength:=0;
  648.   Stat:=0;
  649.   FillChar(ByteBUffer,SizeOf(ByteBuffer),$1D);
  650.   I:=1;
  651.   If (Source=1) Then Begin
  652.     Repeat
  653.       J:= 0;
  654.       Repeat
  655.         J:=Port[StatPort];
  656.       Until ((J and Dsr) = 0);
  657.       B:=Port[DataPort];
  658.       If B<>ACK Then Begin
  659.         Stat:=1;
  660.         PutByte(B);
  661.       End Else Begin
  662.         If (Stat>0) Then Stat:=Stat+1;
  663.       End;
  664.     Until (B=EOX) or (Stat=30);
  665.   End Else Begin
  666.     Assign(AByteFile,DiskFileName);
  667.     Reset(AByteFile);
  668.     Read(AByteFile,B);
  669.     Close(AByteFile);
  670.     If (B=$F0) Then NormFmt:=False;
  671.     Assign(AFile,DiskFileName);
  672.     Reset(Afile);
  673.     FillChar(ByteBuffer,SizeOf(ByteBuffer),$1D);
  674.     If NormFmt Then Begin
  675.       For I:= 1 to 6 do ByteBuffer[i]:=VoiceFormatBytes[I];
  676.       {$I-}
  677.       BlockRead(AFile,ByteBuffer[7],33);
  678.       {$I+}
  679.     End Else Begin
  680.       FS:=FileSize(AFile);
  681.       {$I-}
  682.       BlockRead(AFile,ByteBuffer[1],FS)
  683.       {$I+}
  684.     End;{If}
  685.     If (IOResult>0) or (Not Eof(AFile)) Then Begin
  686.       CLose(AFile);
  687.       Assign(AByteFile,DiskFileName);
  688.       Reset(AByteFile);
  689.       {$I-}
  690.       Seek(AByteFile,4096);
  691.       {$I+}
  692.       If IOResult=0 Then Begin
  693.         BufferLength:=4103;
  694.         Read(AByteFile,B);
  695.         PutByte(B);
  696.         If Not Eof(ABYteFile) Then
  697.         Repeat
  698.           Read(AByteFile,B);
  699.           PutByte(B);
  700.         Until EOF(AByteFile);
  701.       End;
  702.       Close(AByteFile);
  703.     End Else
  704.       If NormFmt Then
  705.         BufferLength:=4230
  706.       Else
  707.         BufferLength:=FS*128;
  708.     Close(AFile);
  709.   End;
  710. End;{GetBUffer}
  711.  
  712. Procedure PutBuffer ( Destination:Integer );
  713. Var I:Integer;
  714.     J,B:Byte;
  715.     CH:Char;
  716.     NormFormat:Boolean;
  717.     Recs:Integer;
  718. Begin
  719.   NormFormat:=Bank[ActiveBank].NormalFormat;
  720.   IF (Destination = 1) Then Begin
  721.     For I:= 1 to BufferLength do PutData(ByteBuffer[I]);
  722.   End Else Begin
  723.     Close(DiskFile);
  724.     Assign(AFile,DiskFileName);
  725.     ReWrite(AFile);
  726.     If NormFormat Then
  727.       Recs:=33
  728.     Else Begin
  729.       Recs:=BufferLength div 128;
  730.       If BufferLength Mod 128 > 0 Then Recs:=Recs+1;
  731.     End;
  732.     BlockWrite(AFile,ByteBuffer,Recs);
  733.     Close(AFile);
  734.   End;
  735. End;{PutBUffer}
  736.  
  737. (* Dump Request routines *)
  738.  
  739.  
  740. Procedure SendDumpRequest;
  741. Var X1,X2,J,K,RS,FP,FS,L,I,X,Y,Ok:Integer;
  742.     ThisRequest:RequestType;
  743.     Same,Adding,Finished,Edit:Boolean;
  744.     S2,S:AnyStr;
  745.     Ch:Char;
  746. Begin
  747.   Adding:=False;
  748.   Finished:=False;
  749.   Assign(DumpRequestFile,'DmpReqst.Dat');
  750.   {$I-}
  751.   Reset(DumpRequestFile);
  752.   {$I+}
  753.   If IOResult>0 Then Rewrite(DumpRequestFile);
  754.   Repeat Until IOResult = 0;
  755.   X1:=3+(40*(0));
  756.   X2:=3+(40+(1));
  757.   Repeat
  758.     ClearBox(3);
  759.     FS:=FileSize(DumpRequestFile);
  760.     Seek(DumpRequestFile,0);
  761.     If (FileSize(DumpRequestFile)>0) Then Begin
  762.       For I:= 1 to FS do Begin
  763.         If (I>12) Then Begin
  764.           X:=X2;Y:=I-12+6;
  765.         End Else Begin
  766.           X:=X1;Y:=I+6;
  767.         End;
  768.         GotoXY(X,Y);
  769.         Read(DumpRequestFile,ThisRequest);
  770.         With ThisRequest do Write(I:3,' : ',Notes);
  771.       End;
  772.     End;
  773.     Edit:=False;
  774.     Repeat
  775.       L:=0;
  776.       RS:=0;
  777.       S:='';
  778.       GetString('Enter the number of the dump request to send (E to Edit) (C to Copy) : ',S,1,24,3);
  779.       If (Length(S)>0) Then Ch:=Copy(S,1,1) Else Ch:=' ';
  780.       If (Ch in ['e','E']) Then Edit:=True Else Val(S,RS,OK);
  781.       If (Ch in ['c','C']) Then Begin
  782.         Repeat
  783.           S:='';
  784.           GetString('Enter the number of the dump request to copy : ',S,1,24,3);
  785.           Val(S,L,OK);
  786.         Until (L in [1..FS]) or EscapeNow;
  787.         Edit:=True;
  788.         Seek(DumpRequestFile,L-1);
  789.         Read(DumpRequestFile,ThisRequest);
  790.         Seek(DumpRequestFile,FS);
  791.         WRite(DumpRequestFile,ThisRequest);
  792.         FS:=FS+1;
  793.         L:=FS;
  794.         RS:=0;
  795.       End;{If}
  796.     Until (RS in [1..FS]) or EscapeNow or Edit;
  797.     If (Not EscapeNow) and Edit Then Begin
  798.       If Not (L in [1..FS]) Then Repeat
  799.         L:=0;
  800.         S:='';
  801.         GetString('Enter the number of the request to EDIT (0 to Add) : ',S,1,24,3);
  802.         Val(S,L,Ok);
  803.       Until (L in [0..FS]) or EscapeNow;
  804.       If L=0 Then Begin
  805.         Seek(DumpRequestFile,FS);
  806.         FP:=FilePos(DumpRequestFile);
  807.         FillChar(ThisRequest,SizeOf(ThisRequest),0);
  808.         ThisRequest.Notes:='';
  809.         ThisRequest.RL:=0;
  810.       End Else Begin
  811.         Seek(DumpRequestFile,L-1);
  812.         FP:=FilePos(DumpRequestFile);
  813.         Read(DumpRequestFile,ThisRequest);
  814.       End;
  815.       If FS>0 Then ClearBox(3);
  816.       X:=X1;
  817.       With ThisRequest do Begin
  818.         GotoXY(X,6);Write(Notes);
  819.         If (RL>0) Then For I:= 1 to RL do Begin
  820.           If (I>12) Then Begin
  821.             X:=X2;Y:=I-12+6;
  822.           End Else Begin
  823.             X:=X1;Y:=I+6;
  824.           End;
  825.           GotoXY(X,Y);Write('Byte Number ',I,' : $'+Hex(RequestBuffer[I]));
  826.         End;
  827.         S:=Notes;
  828.         GetString('Notes : ',S,X1,6,20);
  829.         Notes:=S;
  830.         If Not EscapeNow Then
  831.         Repeat
  832.           S:='';
  833.           L:=0;
  834.           If (RL>0) Then Begin
  835.             Repeat
  836.               L:=0;
  837.               GetString('Enter Number of Byte to Change (0 to Add) (<Esc> to Exit) : ',S,1,24,3);
  838.               Val(S,L,Ok);
  839.             Until (L in [0..RL]) or EscapeNow;
  840.             Finished:=EscapeNow;
  841.             EscapeNow:=False;
  842.           End Else Adding:=True;
  843.           If Not Finished Then Begin
  844.             If (RL=0) or (L=0) Then Begin Adding:=True; End;
  845.             Repeat
  846.               If Adding Then Begin RL:=RL+1;L:=RL; End;
  847.               Str(L,S2);
  848.               S2:='Byte Number '+S2+' : ';
  849.               S:='$'+Hex(RequestBuffer[L]);
  850.               If (L>12) Then Begin
  851.                 X:=X2;Y:=L-12+6;
  852.               End Else Begin
  853.                 X:=X1;Y:=L+6;
  854.               End;
  855.               GetString(S2,S,X,Y,3);
  856.               If EscapeNow Then Begin
  857.                 If Adding Then RL:=RL-1;
  858.               End Else Begin
  859.                 Val(S,J,Ok);
  860.                 RequestBuffer[L]:=J;
  861.               End;
  862.               If EscapeNow Then Adding:=False;
  863.               EscapeNow:=False;
  864.             Until (Not Adding);
  865.           End;{If}
  866.         Until Finished or (L>60);
  867.       End;{With}
  868.       Seek(DumpRequestFile,FP);
  869.       Write(DumpRequestFile,ThisRequest);
  870.     End;{If Edit}
  871.   Until ((RS in [1..FS]) And (Not Edit)) or EscapeNow;
  872.   Uart;
  873.   If (Not EscapeNow) and (RS in [1..FS]) Then Begin
  874.     ClearBox(3);
  875.     Seek(DumpRequestFile,RS-1);
  876.     Read(DumpRequestFile,ThisRequest);
  877.     Close(DumpRequestFile);
  878.     BufferLength:=0;
  879.     X:=X1;
  880.     With ThisRequest do Begin
  881.       GotoXY(X,6);Write(Notes);
  882.       If (RL>0) Then For I:= 1 to RL do Begin
  883.         If (I>12) Then Begin
  884.           X:=X2;Y:=I-12+6;
  885.         End Else Begin
  886.           X:=X1;Y:=I+6;
  887.         End;
  888.         GotoXY(X,Y);Write('Byte Number ',I,' : $'+Hex(RequestBuffer[I]));
  889.       End;
  890.       For I:= 1 to RL Do PutByte(RequestBuffer[I]);
  891.       PutBuffer(1);
  892.       GetBuffer(1);
  893.       Same:=True;
  894.       If (BufferLength=RL) Then Begin
  895.         For I:= 1 to RL do Same:=Same And (RequestBuffer[I]=ByteBuffer[I]);
  896.         If Same Then GetBuffer(1);
  897.       End;
  898.     End;{With}
  899.   End Else
  900.     EscapeNow := True;
  901. End;
  902.  
  903.  
  904.  
  905.  
  906.  
  907.  
  908. (* Main Procedures  ****************************************)
  909.  
  910. Procedure HighLightVoice( C,B,V:Integer );
  911. Var I:Integer;
  912. Begin
  913.   If C=1 Then NormalColor Else SetRedColor;
  914.   If (B=1) Then With Bank[1] DO Begin
  915.     For I:= 1 to 16 do If V=I Then Begin
  916.       GotoXY(5,I+5);
  917.       Write(I:2,'. ',VoiceName[I]);
  918.     End;{for}
  919.     For I:= 17 to 32 do If V=I Then Begin
  920.       GotoXY(24,I-11);
  921.       Write(I:2,'. ',VoiceName[I]);
  922.     End;{For}
  923.   End;{With}
  924.   If (B=2) Then With Bank[2] DO Begin
  925.     For I:= 1 to 16 do If V=I Then Begin
  926.       GotoXY(44,I+5);
  927.       Write(I:2,'. ',VoiceName[I]);
  928.     End;{for}
  929.     For I:= 17 to 32 do If V=I Then Begin
  930.       GotoXY(64,I-11);
  931.       Write(I:2,'. ',VoiceName[I]);
  932.     End;{For}
  933.   End;{With}
  934. End;{HighLightVoice}
  935.  
  936. Procedure DrawBoxes;
  937. Var CBX1,CBX2,CBY1,CBY2,RBX1,RBX2,RBY1,RBY2,I,J,K,N,M:Integer;
  938. Begin
  939.   NormalColor;
  940.   CBX1:=2;CBY1:=5;
  941.   CBX2:=40;CBY2:=22;
  942.   RBX1:=41;RBY1:=5;
  943.   RBX2:=79;RBY2:=22;
  944.   If ActiveBank=1 Then SetRedColor;
  945.   DrawTextBox(1,Bank[1].BankName,Bank[1].Notes,CBX1,CBY1,CBX2,CBY2);
  946.   NormalColor;
  947.   If ActiveBank=2 Then SetRedColor;
  948.   DrawTextBox(1,Bank[2].BankName,Bank[2].Notes,RBX1,RBY1,RBX2,RBY2);
  949.   NormalColor;
  950. End;
  951.  
  952. Procedure DrawVoices;
  953. Var X,Y,B,I:Integer;
  954. Begin
  955.   DrawBoxes;
  956.   For B:= 1 to 2 do Begin
  957.     If Bank[B].NormalFormat Then
  958.       For I := 1 to 32 do HighLightVoice(1,B,I)
  959.     Else Begin
  960.       X:=6+(40*(B-1));
  961.       With Bank[B] do Begin
  962.         GotoXY(X,8);Write('Status : ':25,Hex(Buffer[1]));
  963.         GotoXY(X,9);Write('ID : ':25,Hex(Buffer[2]));
  964.         GotoXY(X,10);Write('Sub Status : ':25,Hex(Buffer[3]));
  965.         GotoXY(x,11);Write('Format Number : ':25,Hex(Buffer[4]));
  966.         GotoXY(X,12);Write('Byte Count 1 : ':25,Hex(Buffer[5]));
  967.         GotoXY(X,13);Write('Byte Count 2 : ':25,Hex(Buffer[6]));
  968.         Y:=(Buffer[5]*128) + Buffer[6];
  969.         GotoXY(X,14);Write('Byte Count   : ':25,Y);
  970.         GotoXY(x,16);Write('Total Bytes in Buffer : ':25,Len);
  971.       End;{With}
  972.     End;{Else}
  973.   End;{For}
  974. End;{DrawVoices}
  975.  
  976.  
  977.  
  978. Type RegRec = record
  979.                 AX, BX, CX, DX, BP, SI, DI, DS, ES, Flags : Integer;
  980.               end;
  981.  
  982.  
  983.  
  984.  
  985.  
  986.  
  987. Function DiskSpace:Real;
  988.  
  989. var
  990.   Tracks,                              { number of available Tracks }
  991.   TotalTracks,                         { number of total Tracks }
  992.   Drive,                               { Drive number }
  993.   Bytes,                               { number of Bytes in one sector }
  994.   Sectors              : Integer;      { number of total Sectors }
  995.   Regs                 : RegRec;
  996.  
  997.  
  998.    procedure DiskStatus( Drive : integer;  var Tracks, TotalTracks,
  999.                          Bytes, Sectors : integer );
  1000.    begin
  1001.      Regs.AX := $3600;               { Get Disk free space }
  1002.      Regs.DX := Drive;               { Store Drive number }
  1003.      MSDos( Regs );                  { Call MSDos to get disk info }
  1004.      Tracks := Regs.BX;              { Get number of Tracks Used }
  1005.      TotalTracks := Regs.DX;         {  "    "    "  total Tracks }
  1006.      Bytes := Regs.CX;               {  "    "    "  Bytes per sector }
  1007.      Sectors := Regs.AX              {  "    "    "  Sectors per cluster }
  1008.    END; { of proc DiskStatus }
  1009.  
  1010. begin
  1011.   Drive:=0;
  1012.   DiskStatus( Drive, Tracks, TotalTracks, Bytes, Sectors );
  1013.   DiskSpace := ((Sectors * Bytes * 1.0) * Tracks);
  1014. end; {Function DiskSpace}
  1015.  
  1016.  
  1017.  
  1018.  
  1019.  
  1020.  
  1021. Procedure GetSubDir( Var SubDir:AnyStr );
  1022. Var Regs : RegRec;
  1023.     I    : Integer;
  1024. begin
  1025.   FillChar(Regs,SizeOf(Regs),0);
  1026.   FillChar(SubDir,SizeOf(SubDir),0);
  1027.   Regs.AX := $4700;          { Get Sub-directory info }
  1028.   Regs.DS := Seg( SubDir );
  1029.   Regs.SI := Ofs( SubDir )+1;
  1030.   MSDos(Regs);               { Execute MSDos call }
  1031.   I:=0;
  1032.   Repeat
  1033.     I:=I+1;
  1034.   Until (SubDir[I]=#0) or (I>64);
  1035.   SubDir[0]:=Chr(I-1);
  1036. end; { of procedure GetSubDir  }
  1037.  
  1038.  
  1039. Procedure GetDefaultDrive( Var Drive:Char );
  1040. Var Regs : RegRec;
  1041.     I    : Integer;
  1042. begin
  1043.   Regs.AX := $1900;                      { Get current Drive number }
  1044.   MSDos( Regs );                         { Call MSDos }
  1045.   I := (Regs.AX and $FF);                { Return value via function }
  1046.   Drive:=Chr(65+I);
  1047. END; { GetDefaultDrive }
  1048.  
  1049.  
  1050. Procedure ChangeSubdir;
  1051. type
  1052.   Int                  = -32767..32767;
  1053.  
  1054. var
  1055.   SubDir2  :AnyStr;
  1056.   Error                : Int;
  1057.  
  1058.        procedure ChangeDir2(Segment, Offset : Integer;
  1059.                                   var Error : Int );
  1060.        var
  1061.          Regs                  : RegRec;
  1062.        begin
  1063.          Regs.DS := segment;
  1064.          Regs.DX := offset;
  1065.          Regs.AX:= $3B00;
  1066.          MSDos( Regs );
  1067.          Error := Regs.AX and $FF;
  1068.        end;
  1069.  
  1070. begin
  1071.   GetString('Enter name of new directory: ',SubDir,1,24,40);
  1072.   For I:= 1 to Length(SubDir) do SubDir[I]:=UpCase(SubDir[I]);
  1073.   If (SubDir[2]<>':') Then SubDir:=Drive+':'+SubDir;
  1074.   If (SubDir[3]<>'\') then Insert('\',SubDir,3);
  1075.   If (SubDir[Length(SubDir)]='\') And (Length(SubDir)>3) Then Begin
  1076.     Delete(SubDir,Length(SubDir),1);
  1077.     Insert(#0,SubDir,Length(SubDir)+1);
  1078.   End;
  1079.   ChangeDir2( DSeg, Ofs( SubDir )+1, Error );
  1080.   if ( Error <> 0 ) then Message(2,'Directory not found.');
  1081.   GetSubDir(SubDir);
  1082. end; { of procedure ChangeDir }
  1083.  
  1084.  
  1085.  
  1086.  
  1087.  
  1088.  
  1089. Procedure ChangeDrive;
  1090. Type  Int       = -32767..32767;
  1091. var
  1092.   Error                : Int;
  1093.   Regs                 : RegRec;
  1094.   I,J                  : Integer;
  1095.   DDrive               : Char;
  1096.   ADrive               : AnyStr;
  1097.   TotDrives            : Integer;
  1098. Begin
  1099.   DDrive:=Drive;
  1100.   J:=Ord(Drive)-65;
  1101.   Regs.DX:= J;
  1102.   Regs.AX:= $E00;
  1103.   MSDos( Regs );
  1104.   TotDrives:=(Regs.AX Mod 256);
  1105.   Repeat
  1106.     ADrive:=Drive;
  1107.     GetString('Enter New Default Drive : ',ADrive,1,24,1);
  1108.     Drive := ADrive[1];
  1109.     Drive := Upcase(Drive);
  1110.     J:=Ord(Drive)-65;
  1111.     If (Not EscapeNow) and (Not ((J+1) in [1..TotDrives])) Then
  1112.       Message(2,'Not a legal drive!');
  1113.   Until ((J+1) in [1..TotDrives]) or EscapeNow;
  1114.   If Not EscapeNow Then Begin
  1115.     Regs.DX:= J;
  1116.     Regs.AX:= $E00;
  1117.     MSDos( Regs );
  1118.   End Else Drive := DDrive;
  1119.   GetSubDir(SubDir);
  1120. end; { of proc ChangeDrive }
  1121.  
  1122.  
  1123.  
  1124.  
  1125.  
  1126.  
  1127. Procedure DirList( Var FileList    : Str20ArrayType;
  1128.                    Var ListLength  : Integer);
  1129. type
  1130.   Char12arr            = array [ 1..12 ] of Char;
  1131.   String20             = string[ 20 ];
  1132.  
  1133. var
  1134.   Regs                 : RegRec;
  1135.   DTA                  : array [ 1..43 ] of Byte;
  1136.   Mask                 : Char12arr;
  1137.   NamR                 : String20;
  1138.   K,Error, I           : Integer;
  1139.  
  1140. begin { main body of program DirList }
  1141.  
  1142.   Message(1,'Processing Directory Information....');
  1143.   ListLength:=0;
  1144.  
  1145.   FillChar(DTA,SizeOf(DTA),0);        { Initialize the DTA buffer }
  1146.   FillChar(Mask,SizeOf(Mask),' ');      { Initialize the mask }
  1147.   FillChar(NamR,SizeOf(NamR),0);      { Initialize the file name }
  1148.  
  1149.   Regs.AX := $1A00;         { Function used to set the DTA }
  1150.   Regs.DS := Seg(DTA);      { store the parameter segment in DS }
  1151.   Regs.DX := Ofs(DTA);      {   "    "      "     offset in DX }
  1152.   MSDos(Regs);              { Set DTA location }
  1153.   Error := 0;
  1154.   If (Length(MaskStr)=0) then
  1155.     MaskStr:=DefaultMaskStr
  1156.   Else Begin
  1157.     If (Copy(MaskStr,Length(MaskStr),1)=':') or
  1158.        (Copy(MaskStr,Length(MaskStr),1)='\') Then Begin
  1159.        MaskStr:=MaskStr+'*.*';
  1160.     End;
  1161.   End;
  1162.   For I:= 1 to Length(MaskStr) do Mask[I]:=MaskStr[I];
  1163.  
  1164.  
  1165.   Regs.AX := $4E00;          { Get first directory entry }
  1166.   Regs.DS := Seg(Mask);      { Point to the file Mask }
  1167.   Regs.DX := Ofs(Mask);
  1168.   Regs.CX := 22;             { Store the option }
  1169.   MSDos(Regs);               { Execute MSDos call }
  1170.   Error := Regs.AX and $FF;  { Get Error return }
  1171.   I := 1;                    { initialize 'I' to the first element }
  1172.   if (Error = 0) then Begin
  1173.     repeat
  1174.       NamR[I] := Chr(Mem[Seg(DTA):Ofs(DTA)+29+I]);
  1175.       I := I + 1;
  1176.     until not (NamR[I-1] in [' '..'~']) or (I>20);
  1177.     NamR[0] := Chr(I-1);        { set string length because assigning }
  1178.                                 { by element does not set length }
  1179.     If (Length(NamR)>1) and (NamR<>'..') Then Begin
  1180.       ListLength:=ListLength+1;
  1181.       FileList[ListLength]:=NamR;
  1182.     End;
  1183.   End;{If}
  1184.   while (Error = 0) do begin
  1185.     Error := 0;
  1186.     Regs.AX := $4F00;           { Function used to get the next }
  1187.                                 { directory entry }
  1188.     Regs.CX := 22;              { Set the file option }
  1189.     MSDos( Regs );              { Call MSDos }
  1190.     Error := Regs.AX and $FF;   { get the Error return }
  1191.     I := 1;
  1192.     repeat
  1193.       NamR[I] := Chr(Mem[Seg(DTA):Ofs(DTA)+29+I]);
  1194.       I := I + 1;
  1195.     until not (NamR[I-1] in [' '..'~'] ) or (I > 20);
  1196.     NamR[0] := Chr(I-1);
  1197.     If (Error = 0) and (Length(NamR)>1) and (NamR<>'..') Then Begin
  1198.       ListLength:=ListLength+1;
  1199.       FileList[ListLength]:=NamR;
  1200.     End;{If}
  1201.   end;{While}
  1202. end; { of program DirList  }
  1203.  
  1204. Procedure DrawScreen;
  1205. Var S:AnyStr;
  1206.     I:Integer;
  1207. Begin
  1208.   If (ScreenNum=1) Then Begin
  1209.     ClrScr;
  1210.     InverseColor;
  1211.     GotoXY(2,2);Write
  1212.     ('  F1      F2      F3      F4      F5      F6      F7      F8      F9      F10 ');
  1213.     GotoXY(2,3);Write
  1214.     (' Midi    Midi    File    File   Toggle   Move   Change  Change   Drive    Exit');
  1215.     GotoXY(2,4);Write
  1216.     (' Load    Dump    Load    Save    Bank    Voice  V-Name   Notes    Menu        ');
  1217.   End Else If (ScreenNum=2) Then Begin
  1218.     InverseColor;
  1219.     GotoXY(2,2);Write
  1220.     ('    F1              F2              F3               F4             F10       ');
  1221.     GotoXY(2,3);Write
  1222.     ('  Change          Change          Change          Directory         Main      ');
  1223.     GotoXY(2,4);Write
  1224.     ('  Drive           SubDir           Mask            Listing          Menu      ');
  1225.   End;
  1226.   Str(DiskSpace:8:0,S);
  1227.   S:=Drive+':'+Subdir+'\'+MaskStr+'        '+S+' bytes available';
  1228.   DrawTextBox(2,'Randy''s Dx/Tx Dumpster',S,1,1,80,23);
  1229.   NormalColor;
  1230. End;
  1231.  
  1232.  
  1233. Procedure GetNames( Var ThisBank : BankType);
  1234. Var N,I:Integer;
  1235.     St:Str10;
  1236. Begin
  1237.   With ThisBank Do Begin
  1238.     For I:= 1 to 32 do Begin
  1239.       St[0]:=Chr(10);
  1240.       For N:= 1 to 10 do Begin
  1241.         St[N]:=Chr(Voice[I,118+N]);
  1242.         VoiceName[I]:=St;
  1243.       End;
  1244.     End;
  1245.   End;
  1246. End;
  1247.  
  1248. Procedure LoadBuffer(Source:Integer);
  1249. Var FormatOk,OverWriteYn:Boolean;
  1250.     OverWrite:Char;
  1251.     L,MidiError,I,J,K:Integer;
  1252.     AString,S1,S2:AnyStr;
  1253.     Ch:Char;
  1254. Begin
  1255.   ThisBank.NormalFormat:=True;
  1256.   If BufferLength>6 Then Begin
  1257.      MidiError:=0;
  1258.      Position:=1;
  1259.      Repeat
  1260.        GetByte(B);
  1261.      Until (B=$F0) or (Position>BufferLength);
  1262.      Message(0,'Processing Format Bytes');
  1263.      ThisFormat[1]:=$F0;
  1264.      For I:= 2 to 6 do Begin
  1265.        GetByte(ThisFormat[I]);
  1266.      End;{For}
  1267.      FormatOK:=True;
  1268.      For I:=1 to 6 do FormatOK:= FormatOK and (ThisFormat[i]=VoiceFormatBytes[I]);
  1269.      If Not FormatOK Then Begin
  1270.        ThisBank.NormalFormat:=False;
  1271.        MidiError:=1;
  1272.      End;
  1273.      If (MidiError=0) and ThisBank.NormalFormat Then With ThisBank do Begin
  1274.        Message(0,'Processing Voice Bytes');
  1275.        J:=1;
  1276.        Repeat
  1277.          I:=1;
  1278.          Repeat
  1279.            GetByte(Voice[j,i]);
  1280.            I:=I+1;
  1281.          Until (I>128) or KeyPressed;
  1282.          J:=J+1;
  1283.        Until (j>32) or KeyPressed;
  1284.        CheckTheSum(Voice,CheckSum);
  1285.        GetByte(B);
  1286.        If (B<>Checksum) Then Midierror:=2;
  1287.        If (Source=1) Then GetByte(B) Else B:=EOX;
  1288.        If (B<>EOX) Then Begin
  1289.          MidiError:=3;
  1290.        End;
  1291.        If (Source=2) Then Begin
  1292.          L:=0;
  1293.          For I:= 1 to 20 Do Begin
  1294.            GetByte(B);
  1295.            If (B in [32..127]) Then Begin
  1296.              L:=L+1;
  1297.              Notes[I]:=Chr(B);
  1298.            End;
  1299.          End;{for}
  1300.          If L=0 Then Notes:='' Else Notes[0]:=Chr(L-1);
  1301.        ENd Else
  1302.          Notes:='';
  1303.      End;{If/With}
  1304.      If Not ThisBank.NormalFormat Then With ThisBank do Begin
  1305.        Message(0,'Processing Bytes....    Not a DX/TX Format....');
  1306.        Buffer:=ByteBuffer;
  1307.        Len:=BufferLength;
  1308.        Position:=1;
  1309.        If (Source=2) Then Begin
  1310.          Repeat
  1311.            GetByte(B);
  1312.          Until (B=EOX);
  1313.          L:=0;
  1314.          For I:= 1 to 20 Do Begin
  1315.            GetByte(B);
  1316.            If (B in [32..127]) Then Begin
  1317.              L:=L+1;
  1318.              Notes[I]:=Chr(B);
  1319.            End;
  1320.          End;{for}
  1321.          If L=0 Then Notes:='' Else Notes[0]:=Chr(L-1);
  1322.        End Else
  1323.          Notes:='';
  1324.      End;{If/With}
  1325.      Case MidiError Of
  1326.        2 : Message(2,'Checksum Error !');
  1327.        3 : Message(2,'EOX Error');
  1328.      End;{Case}
  1329.      Bank[ActiveBank]:=ThisBank;
  1330.      With Bank[ActiveBank] do Begin
  1331.        Exists:=True;
  1332.        If Source=1 Then BankName:='MidiPort' Else BankName:=DiskFileName;
  1333.        If Source=1 Then Saved:=False Else Saved:=True;
  1334.      End;{With}
  1335.      If ThisBank.NormalFormat Then GetNames(Bank[ActiveBank]);
  1336.   End Else Begin
  1337.     Message(2,'No Sys-Ex Midi Data was received !');
  1338.   End;
  1339. End;{LoadBuffer}
  1340.  
  1341. Procedure GetDiskFile;
  1342. Var S,AString : AnyStr;
  1343.     ListLength,
  1344.     X,Y,J,Ok,
  1345.     X1,X2,X3,X4,
  1346.     Choice,
  1347.     I,L     : Integer;
  1348.     FileList: Str20ArrayType;
  1349.  
  1350. Begin
  1351.   Repeat
  1352.     DirList(FileList,ListLength);
  1353.     X1:=2;X2:=28;X3:=54;
  1354.     I:=1;
  1355.     If ListLength>0 Then Begin
  1356.       Repeat
  1357.         Repeat
  1358.           Y:=5;
  1359.           If X=X1 Then
  1360.             X:=X2
  1361.           Else if X=X2 Then
  1362.             X:=X3
  1363.           Else Begin
  1364.             ClrScr;
  1365.             DrawScreen;
  1366.             X:=X1;
  1367.           End;
  1368.           Repeat
  1369.             GotoXY(X,Y);
  1370.             Write(I:2,':',FileList[I]);
  1371.             I:=I+1;
  1372.             Y:=Y+1;
  1373.           Until (Y=23) or (I>ListLength);
  1374.         Until (X=X3) or (I>ListLength);
  1375.         Repeat
  1376.           DiskFileName:='';
  1377.           J:=0;
  1378.           GetString('Enter Number of File to Load : ',DiskFileName,1,24,4);
  1379.           If Not EscapeNow then Val(DiskFileName,J,OK);
  1380.           If (Ok>0) or (not J in [0..ListLength]) Then
  1381.             Message(2,'Illegal Number !');
  1382.         Until (OK=0) and (J in [0..ListLength]) or EscapeNow;
  1383.         If (I>ListLength) Then I:=1;
  1384.         X:=0;
  1385.       Until (J>0) or (EscapeNow);
  1386.       DiskFileName:=FileList[J];
  1387.     End Else Begin
  1388.       DiskFileName:='ksqivnks.8vm';
  1389.     End;
  1390.   Until (Length(DiskFileName)>1) or EscapeNow;
  1391.   If (Not EscapeNow) and (DiskExist(DiskFileName)) Then Begin
  1392.     Bank[ActiveBank].BankName:=DiskFileName;
  1393.     Assign(DiskFile,DiskFileName);
  1394.     Message(0,'Loading File From Disk .......');
  1395.     GetBuffer(2);
  1396.     LoadBuffer(2);
  1397.     Close(DiskFile);
  1398.   End Else Begin
  1399.     If Not EscapeNow Then Message(2,'File Does Not Exist !!! ');
  1400.   End;
  1401. End;{GetDiskFile}
  1402.  
  1403.  
  1404.  
  1405. Procedure SaveDiskFile;
  1406. Var S:AnyStr;
  1407.     OK:Boolean;
  1408.     Ch:Char;
  1409. Begin
  1410.   Ok:=False;
  1411.   Repeat
  1412.     DiskFileName:=Bank[ActiveBank].BankName;
  1413.     GetString('Enter Full File Name to Save to : ',DiskFileName,1,24,20);
  1414.     If DiskExist(DiskFilename) Then Begin
  1415.       GetChar(2,'File Already Exists !!!!     Replace  ?? ',Ch);
  1416.       If (CH in ['y','Y']) Then Begin
  1417.         OK:=True;
  1418.       End;
  1419.     End Else If Not DiskValid(DiskFileName) Then Begin
  1420.       If Not EscapeNow Then Message(2,'File Name is not Legal !');
  1421.     End Else
  1422.       OK:=True;
  1423.   Until EscapeNow or Ok;
  1424.   If Not EscapeNow Then Begin
  1425.     Bank[ActiveBank].BankName:=DiskFileName;
  1426.     DrawBoxes;
  1427.     Message(0,'Saving Active Bank to Disk.....');
  1428.     Assign(DiskFile,DiskFileName);
  1429.     Rewrite(DiskFile);
  1430.     FillChar(ByteBuffer,SizeOf(ByteBuffer),0);
  1431.     BufferLength:=0;
  1432.     With Bank[ActiveBank] do Begin
  1433.       If NormalFormat Then Begin
  1434.         J:=1;
  1435.         Repeat
  1436.           I:=1;
  1437.           Repeat
  1438.             PutByte(Voice[j,i]);
  1439.             I:=I+1;
  1440.           Until (I>128) or (Ch=^M) or KeyPressed;
  1441.           J:=J+1;
  1442.         Until (j>32) or (Ch=^M) or KeyPressed;
  1443.         CheckTheSum(Voice,CheckSum);
  1444.         PutByte(CheckSum);
  1445.         For I:= 1 to 20 Do PutByte(Ord(Notes[I]));
  1446.       End Else Begin
  1447.         ByteBuffer:=Buffer;
  1448.         BufferLength:=Len;
  1449.       End;
  1450.       Saved:=True;
  1451.       Exists:=True;
  1452.     End;{With}
  1453.     PutBuffer(2);
  1454.     Close(DiskFile);
  1455.   End;
  1456.   Str(DiskSpace:8:0,S);
  1457.   S:=Drive+':'+Subdir+'\'+MaskStr+'        '+S+' bytes available';
  1458.   DrawTextBox(2,'Randy''s Dx/Tx Dumpster',S,1,1,80,23);
  1459. End;{SaveDiskFile}
  1460.  
  1461.  
  1462. Procedure DumpToMidi;
  1463. Var X,Y,I,J,K:Integer;
  1464.     AName:AnyStr;
  1465.     ABank:BankType;
  1466. Begin
  1467.  If Not Bank[ActiveBank].Exists Then Begin
  1468.    GetDiskFile;
  1469.    DrawVoices;
  1470.  End;
  1471.  If Not EscapeNow Then Begin
  1472.   Message(0,'Dumping Current Bank to Midi .....');
  1473.   BufferLength:=0;
  1474.   With Bank[ActiveBank] do Begin
  1475.     If NormalFormat Then Begin
  1476.       CheckTheSum(Voice,CheckSum);
  1477.       For I:= 1 to 6 do PutByte(VoiceFormatBytes[i]);
  1478.       J:=1;
  1479.       Repeat
  1480.         I:=1;
  1481.         Repeat
  1482.           PutByte(Voice[j,i]);
  1483.           I:=I+1;
  1484.         Until (I>128) or KeyPressed;
  1485.         J:=J+1;
  1486.       Until (j>32) or KeyPressed;
  1487.       PutByte(CheckSum);
  1488.       PutByte(EOX);
  1489.     End Else Begin
  1490.       ByteBuffer:=Buffer;
  1491.       BufferLength:=Len;
  1492.     End;
  1493.   End;{With}
  1494.   PutBuffer(1);
  1495.  End;{If not EscapeNow};
  1496. End;{DumpToMidi}
  1497.  
  1498.  
  1499.  
  1500. Procedure CheckBanks;
  1501. Var Ch:Char;
  1502. Begin
  1503.   If ((ActiveBank=1) Or Exit) and (Not Bank[1].Saved) Then Begin
  1504.     GetChar(2,'Bank 1 not saved to disk !!  Do you want to save it ?',Ch);
  1505.     If (Ch in ['y','Y']) Then SaveDiskFile Else Bank[ActiveBank].Saved := True;
  1506.   End;{if}
  1507.   If ((ActiveBank=2) or Exit) And (Not Bank[2].Saved) Then Begin
  1508.     GetChar(2,'Bank 2 not saved to disk !!  Do you want to save it ?',Ch);
  1509.     If (Ch in ['y','Y']) Then SaveDiskFile Else Bank[ActiveBank].Saved := True;
  1510.   End;{if}
  1511. End;{CheckBanks}
  1512.  
  1513.  
  1514.  
  1515.  
  1516.  
  1517. Procedure SendMidiBank;
  1518. Begin
  1519.   DumpToMidi;
  1520. End;
  1521.  
  1522. Procedure GetMidiBank;
  1523. Var Ch:Char;
  1524. Begin
  1525.   CheckBanks;
  1526.   If Not EscapeNow THen Begin
  1527.     GetChar(1,'Do you want to Send/Edit a dump request ? ',Ch);
  1528.     If (Ch in ['y','Y']) Then
  1529.       SendDumpRequest
  1530.     Else Begin
  1531.       Message(1,'Go Ahead and Send Midi Sys-Ex.....');
  1532.       Uart;
  1533.       GetBuffer(1);
  1534.     End;
  1535.     If Not EscapeNow Then Message(1,'Midi Received');
  1536.     If Not EscapeNow Then LoadBuffer(1);
  1537.   End;
  1538.   DrawScreen;
  1539.   DrawVoices;
  1540. End;
  1541.  
  1542. Procedure ChooseBank;
  1543. Begin
  1544.   CheckBanks;
  1545.   If Not EscapeNow Then GetDiskFile;
  1546.   DrawScreen;
  1547.   DrawVoices;
  1548. End;
  1549.  
  1550. Procedure MoveVoices;
  1551. Var A,i,Ok,B1,B2,V1,V2:Integer;
  1552.     S,SB1,SB2,SV1,SV2:AnyStr;
  1553.     Ch:Char;
  1554.     A1,A2:Boolean;
  1555. Begin
  1556.   A:=0;
  1557.   For I := 1 to 2 do If Bank[I].NormalFormat Then A:=A+1;
  1558.   A1:=Bank[1].NormalFormat;
  1559.   A2:=Bank[2].NormalFormat;
  1560.   If A>1 Then
  1561.     Repeat
  1562.       SB1:='';
  1563.       GetString('Enter Source Bank # (1-2) : ',SB1,1,24,2);
  1564.       Val(SB1,B1,Ok);
  1565.     Until (B1 in [1,2]) or EscapeNow
  1566.   Else
  1567.     If A>0 Then
  1568.       If A1 Then B1:=1 Else B1:=2
  1569.     Else
  1570.       EscapeNow:=True;
  1571.   If Not EscapeNow Then Repeat
  1572.     SV1:='';
  1573.     GetString('Enter Source Voice # (1-32) : ',SV1,1,24,3);
  1574.     Val(SV1,V1,Ok);
  1575.   Until (V1 in [1..32]) or EscapeNow;
  1576.   If Not EscapeNow Then HighLightVoice(2,B1,V1);
  1577.   If Not EscapeNow Then
  1578.     If A>1 Then
  1579.       Repeat
  1580.         SB2:='';
  1581.         GetString('Enter Destination Bank # (1-2) : ',SB2,1,24,2);
  1582.         Val(SB2,B2,Ok);
  1583.       Until (B2 in [1,2]) or EscapeNow
  1584.     Else
  1585.       If A1 Then B2:=1 Else B2:=2;
  1586.   If Not EscapeNow Then Repeat
  1587.     SV2:='';
  1588.     GetString('Enter Destination Voice # (1-32) : ',SV2,1,24,3);
  1589.     Val(SV2,V2,Ok);
  1590.   Until (V2 in [1..32]) or EscapeNow;
  1591.   If Not EscapeNow Then Begin
  1592.     With Bank[B2] do Begin
  1593.       Voice[V2]:=Bank[B1].Voice[V1];
  1594.       VoiceName[V2]:=Bank[B1].VoiceName[V1];
  1595.       Exists:=True;
  1596.       Saved:=False;
  1597.       CheckTheSum(Voice,CheckSum);
  1598.     End;
  1599.     Message(0,'Moving....');
  1600.     HighlightVoice(1,B1,V1);
  1601.     HighlightVoice(1,B2,V2);
  1602.   End;
  1603. End;{MoveVoices}
  1604.  
  1605.  
  1606. Procedure GetVoiceName;
  1607. Var S:AnyStr;
  1608.     A,I,V,Ok,B:Integer;
  1609.     A1,A2:Boolean;
  1610. Begin
  1611.   A:=0;
  1612.   For I := 1 to 2 do If Bank[I].NormalFormat Then A:=A+1;
  1613.   A1:=Bank[1].NormalFormat;
  1614.   A2:=Bank[2].NormalFormat;
  1615.   If A>1 Then
  1616.     Repeat
  1617.       S:='';
  1618.       GetString('Enter Bank # : ',S,1,24,2);
  1619.       Val(S,B,Ok);
  1620.     Until (B in [1,2]) or EscapeNow
  1621.   Else
  1622.     If A>0 Then
  1623.       If A1 Then B:=1 Else B:=2
  1624.     Else
  1625.       EscapeNow:=True;
  1626.   If Not EscapeNow Then Repeat
  1627.     S:='';
  1628.     GetString('Enter Voice # : ',S,1,24,3);
  1629.     Val(S,V,Ok);
  1630.   Until (V in [1..32]) or EscapeNow;
  1631.   If Not EscapeNow Then Begin
  1632.     With Bank[B] Do Begin
  1633.       S:=VoiceName[V];
  1634.       GetString('Enter VoiceName : ',S,1,24,10);
  1635.       VoiceName[v]:=S;
  1636.       For I:= 1 to 10 do Voice[V,118+I]:=Ord(S[i]);
  1637.     End;{With}
  1638.     GetNames(Bank[B]);
  1639.     With Bank[B] do Begin
  1640.       CheckTheSum(Voice,CheckSum);
  1641.       Exists:=True;
  1642.       Saved:=False;
  1643.     End;{with}
  1644.   End;
  1645.   If Not EscapeNow Then HighLightVoice(1,B,V);
  1646. End;
  1647.  
  1648. Procedure GetNotes;
  1649. Var S:AnyStr;
  1650.     I,V,Ok,B:Integer;
  1651. Begin
  1652.   Repeat
  1653.     S:='';
  1654.     GetString('Enter Bank # : ',S,1,24,2);
  1655.     Val(S,B,Ok);
  1656.   Until (B in [1,2]) or EscapeNow;
  1657.   If Not EscapeNow Then Begin
  1658.     With Bank[B] Do Begin
  1659.       S:=Notes;
  1660.       GetString('Enter Notes : ',S,1,24,20);
  1661.       Notes:=S;
  1662.     End;{With}
  1663.     Bank[B].Exists:=True;
  1664.     Bank[B].Saved:=False;
  1665.     DrawBoxes;
  1666.   End;
  1667. End;
  1668.  
  1669. Procedure DoDirList(Var FilesExist:Boolean);
  1670. Var AString : AnyStr;
  1671.     CH      : Char;
  1672.     ListLength,
  1673.     X,Y,J,Ok,
  1674.     X1,X2,X3,X4,
  1675.     Choice,
  1676.     I,L     : Integer;
  1677.     FileList: Str20ArrayType;
  1678. Begin
  1679.   FilesExist:=True;
  1680.   FillChar(FileList,SizeOf(FileList),' ');
  1681.   DirList(FileList,ListLength);
  1682.   X1:=2;X2:=28;X3:=54;
  1683.   X:=0;
  1684.   I:=1;
  1685.   If ListLength>0 Then Begin
  1686.     Repeat
  1687.       Repeat
  1688.         Y:=5;
  1689.         If X=X1 Then
  1690.           X:=X2
  1691.         Else if X=X2 Then
  1692.           X:=X3
  1693.         Else Begin
  1694.           ClrScr;
  1695.           DrawScreen;
  1696.           X:=X1;
  1697.         End;
  1698.         Repeat
  1699.           GotoXY(X,Y);
  1700.           Write(I:2,':',FileList[I]);
  1701.           I:=I+1;
  1702.           Y:=Y+1;
  1703.         Until (Y=23) or (I>ListLength);
  1704.       Until (X=X3) or (I>ListLength);
  1705.       If (I<ListLength) or (ScreenNum = 1) Then
  1706.         Message(2,'Press Any Key To Continue');
  1707.     Until (I>ListLength);
  1708.   End Else Begin
  1709.     Message(2,'No files exist within the current Directory\Mask !!!');
  1710.     FilesExist:=False;
  1711.   End;
  1712. ENd;
  1713.  
  1714.  
  1715. Procedure ChangeMask;
  1716. Var S,S2:AnyStr;
  1717.     MaskOk:Boolean;
  1718. Begin
  1719.   S2:=MaskStr;
  1720.   Repeat
  1721.     S:=MaskStr;
  1722.     GetString('Enter Mask : ',S,1,24,12);
  1723.     MaskStr:=S;
  1724.     DoDirList(MaskOK);
  1725.   Until MaskOk or EscapeNow;
  1726.   If Not MaskOk Then MaskStr:=S2;
  1727. End;
  1728.  
  1729.  
  1730.  
  1731.  
  1732.  
  1733.  
  1734.  
  1735. Procedure ToggleBank;
  1736. Begin
  1737.   ActiveBank:=Other(ActiveBank);
  1738.   DrawBoxes;
  1739. End;
  1740.  
  1741.  
  1742.  
  1743. (* Voice Edit Procedures  ****************************************)
  1744.  
  1745. Procedure EditVoice;
  1746. Var S:AnyStr;
  1747.     I,V,Ok,B:Integer;
  1748.     ThisVoice:VoiceType;
  1749. Begin
  1750.   GetVoiceName;
  1751.   (*
  1752.      A voice editing menu would go here.  Haven't written it yet...
  1753.      For me, it is easier to program the dx7 from the dx7!!  (I got
  1754.      mine when they first came out and have gotten used to it).....
  1755.      If anyone writes some routines for this section, please send
  1756.      them to me!  They shouldn't be too hard!
  1757.   *)
  1758. End;
  1759.  
  1760.  
  1761.  
  1762. Procedure DiskMenu;
  1763. Var S:AnyStr;
  1764.     I:Integer;
  1765.     Bool:Boolean;
  1766. Begin
  1767.   ScreenNum:=2;
  1768.   DoDirList(Bool);
  1769.   Repeat
  1770.     Message(0,'Ready');
  1771.     TC:=#32;
  1772.     Repeat
  1773.       Repeat Read(Kbd,TC); Until TC=#27;
  1774.       Read(Kbd,TC2);
  1775.     Until (TC2 in [F1..F4,F10]);
  1776.     Case TC2 of
  1777.       F1 : ChangeDrive;
  1778.       F2 : ChangeSubDir;
  1779.       F3 : ChangeMask;
  1780.       F4 : DoDirList(Bool);
  1781.     End;{Case}
  1782.     If (Tc2 in [F1..F2]) Then DoDirList(Bool);
  1783.   Until (TC2=F10) or EscapeNow;
  1784.   ScreenNum:=1;
  1785.   DrawScreen;
  1786.   DrawVoices;
  1787. End;
  1788.  
  1789.  
  1790.  
  1791. Procedure MainMenu;
  1792. Begin
  1793.   EscapeNow:=False;
  1794.   Message(0,'Ready.');
  1795.   Repeat
  1796.     Repeat Read(Kbd,TC); Until TC=#27;
  1797.     Read(Kbd,TC2);
  1798.   Until (TC2 in PossibleChoicesSet);
  1799.   Case TC2 of
  1800.     F1     : GetMidiBank;
  1801.     F2     : SendMidiBank;
  1802.     F3     : ChooseBank;
  1803.     F4     : SaveDiskFile;
  1804.     F5     : ToggleBank;
  1805.     F6     : MoveVoices;
  1806.     F7     : EditVoice;
  1807.     F8     : GetNotes;
  1808.     F9     : DiskMenu;
  1809.     F10    : Exit:=True;
  1810.   End;{Case}
  1811. End; {MainMenu}
  1812.  
  1813.  
  1814. (* Main Program  *******************************************************)
  1815.  
  1816. Begin
  1817.   Uart;
  1818.   For I:= 1 to 2 do Begin
  1819.     FillChar(Bank[I],Sizeof(Bank[I]),0);
  1820.     With Bank[I] do Begin
  1821.       Saved:=True;
  1822.       Exists:=False;
  1823.       BankName:='Empty Bank';
  1824.       Notes:='';
  1825.     End;
  1826.   End;
  1827.   DiskFileName:='';
  1828.   DefaultMaskStr:='*.*';
  1829.   MaskStr:=DefaultMaskStr;
  1830.   GetSubDir(SubDir);
  1831.   GetDefaultDrive(Drive);
  1832.   ActiveBank:=1;
  1833.   SetGraphSet;
  1834.   Exit:=False;
  1835.   PossibleChoicesSet:=[F1..F10];
  1836.   ScreenNum:=1;
  1837.   DrawScreen;
  1838.   DrawVoices;
  1839.   Repeat
  1840.     Ok:=True;
  1841.     MainMenu;
  1842.   Until Exit;
  1843.   CheckBanks;
  1844.   ClrScr;
  1845.   GotoXY(1,3);
  1846.   Writeln('Have a nice night....');
  1847. End.
  1848.